Skip to content

writes: auto-sync / continuous self-heal loop (#29) - #40

Merged
lex00 merged 1 commit into
mainfrom
feat/29-auto-sync
Jul 14, 2026
Merged

lex00 merged 1 commit into
mainfrom
feat/29-auto-sync

Conversation

@lex00

@lex00 lex00 commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Closes #29 (epic #23). The marquee Argo write feature — opt-in, off by default.

With --env + --poll, --auto-sync apply triggers the project's ApplyOp (heal the cloud toward source) on a polled drift; pull-request triggers the ReconcileOp (adopt live → PR).

Safe by construction: delegated + gated as ever — behold triggers a committed Op on the executor and holds no creds; a gated (destructive) apply still pauses for Approve — auto-sync never approves. Source edits don't auto-sync (a new declaration is new desired state, not drift); only polled drift does. Off unless explicitly enabled.

How

  • src/op-runner.tsOpRunner: one place an Op is triggered, shared by the HTTP routes and the auto-sync loop, so both honour a single running-guard and the post-op frame capture. Replaces the inline run logic in POST /api/ops/:name/run.
  • src/autosync.tsAutoSyncMode + pickAutoSyncOp (pure: off / running / no-matching-op → null). Unit-tested.
  • server — poll drift → pickAutoSyncOprunner.trigger; /api/ops exposes autoSync.
  • cli--auto-sync off|apply|pull-request (requires --env + --poll); boot log.
  • web — auto-sync banner; each trigger streams to the now-line (⟳ auto-sync (apply) → prod-apply).

Verified

  • CLI rejects --auto-sync without --env+--poll, and invalid modes.
  • /api/ops surfaces autoSync; runner-backed Sync/Adopt routes unchanged.
  • tsc + node --check clean; 48 tests (+6 autosync).
  • Auto-apply not live-fired (would mutate real infra); decision logic unit-tested, wiring smoke-verified.

Opt-in. With --env + --poll, `--auto-sync apply` triggers the project's ApplyOp
(heal the cloud toward source) on a polled drift; `pull-request` triggers the
ReconcileOp (adopt live → PR). Off by default. Delegated + gated as ever: behold
triggers a committed Op on the executor; a gated destructive apply still pauses
for Approve — auto-sync never approves. Source edits don't auto-sync (new
declaration = new desired state, not drift); only polled drift does.

- src/op-runner.ts: OpRunner — one place an Op is triggered, shared by the HTTP
  routes and the auto-sync loop, so both honour one running-guard and the post-op
  frame capture. Replaces the inline run logic in the route.
- src/autosync.ts: AutoSyncMode + pickAutoSyncOp (pure; off/running/no-op → null).
- server: poll drift → pickAutoSyncOp → runner.trigger; /api/ops exposes autoSync.
- cli: --auto-sync off|apply|pull-request (needs --env + --poll); boot log.
- web: auto-sync banner; the trigger streams to the now-line.

tsc + 48 tests (+6 autosync). Auto-apply not live-fired (would mutate real
infra); decision logic unit-tested, wiring smoke-verified.
@lex00
lex00 merged commit 93a5a02 into main Jul 14, 2026
1 check passed
@lex00
lex00 deleted the feat/29-auto-sync branch July 14, 2026 04:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

writes: auto-sync / continuous reconcile loop (Argo auto-sync + self-heal)

1 participant